﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.DirectoryServices;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.International.Converters.PinYinConverter;
using System.Net;
namespace WinUserAcc
{
    public partial class frmComputercs : Form
    {
        public frmLogin login;
        private bool isExit = true;

        public string UserName;
        public string Pwd;
        private string _companyPath = "";

        //在程序的生存期内不发生更改的不可变值
        public const string PROTOCOL = "LDAP://";

        public readonly string CONGIGURATION;
        public frmComputercs()
        {
            InitializeComponent();
            CONGIGURATION = Common.Domain;
        }

        #region 关闭按钮事件
        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close(); //关闭窗口
        }
        #endregion

        #region 窗体关闭事件
        private void frmComputercs_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (isExit)
            {
                DialogResult result = MessageBox.Show("是否退出？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (result == DialogResult.No)
                {
                    e.Cancel = true;
                    return;
                }

                this.Dispose();
                Application.ExitThread();
            }
        }
        #endregion

        #region 窗体加载事件
        private void frmComputercs_Load(object sender, EventArgs e)
        {
            InitCurrentCompany();
            cmbOrganization.Nodes.Add(GetAll());

        }
        #endregion

        #region 删除计算机信息
        private void toolStripLabel3_Click(object sender, EventArgs e)
        {
            int k = dgvComputerInfo.SelectedRows.Count;
            if (k > 0)
            {
                DialogResult RSS = MessageBox.Show(this, "你确定要删除" + Convert.ToString(k) + "个对象吗？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
                switch (RSS)
                {
                    case DialogResult.OK:
                        for (int i = this.dgvComputerInfo.SelectedRows.Count; i > 0; i--)
                        {
                            int ID = Convert.ToInt32(dgvComputerInfo.SelectedRows[i - 1].Cells[0].Value);
                            dgvComputerInfo.Rows.RemoveAt(dgvComputerInfo.SelectedRows[i - 1].Index);//从集合中删除选中的行

                        }
                        break;
                    case DialogResult.Cancel:
                        break;
                }
            }
            this.txtComputerName.Text = "";
            this.txtDescribe.Text = "";
            for (var i = 0; i < dgvComputerInfo.Rows.Count; i++)
            {
                dgvComputerInfo.Rows[i].Cells[0].Value = i + 1;
            }
        }
        #endregion

        #region 清空dgvUserInfo数据
        private void toolStripLabel4_Click(object sender, EventArgs e)
        {
            int k = dgvComputerInfo.SelectedRows.Count;
            if (k > 0)
            {
                DialogResult result = MessageBox.Show("你确定要清空对象吗？", "提示", MessageBoxButtons.OKCancel,
                    MessageBoxIcon.Warning);
                if (result == DialogResult.OK)
                {

                    this.dgvComputerInfo.Rows.Clear(); //清空数据

                    dgvComputerInfo.Refresh();
                }
                else
                {
                    result = DialogResult.Cancel;
                }
            }
            this.txtComputerName.Text = "";
            this.txtDescribe.Text = "";

        }
        #endregion

        #region 修改计算机信息
        private void toolStripLabel2_Click(object sender, EventArgs e)
        {
            var row = dgvComputerInfo.CurrentRow;
            dgvComputerInfo.Tag = row;
            if (row != null)
            {
                gbCom.Text = "修改";
                tslAddOrSave.Text = "保存";
                tslModify.Enabled = false;
                tslDelete.Enabled = false;
                tslClear.Enabled = false;
                txtComputerName.Text = row.Cells["comName"].Value.ToString();
                txtDescribe.Text = row.Cells["Description"].Value.ToString();
                cmbOrganization.SelectedNode = row.Cells["selectedNode"].Value as TreeNode;

            }

        }
        #endregion

        #region 添加计算机信息
     
        private void toolStripLabel1_Click(object sender, EventArgs e)
        {
            
            //var desc = this.txtDescribe.Text.Trim();

            var comName = this.txtComputerName.Text.Trim();


            var strArray = comName.Split('-');
            comName = strArray[0].ToUpper() + comName.Substring(strArray[0].Length);

            if (verification(comName)) //非空
            {

                try
                {
                    DataGridViewRow dgvRow;

                    if (tslAddOrSave.Text == "保存")
                    {
                        dgvRow = dgvComputerInfo.Tag as DataGridViewRow;
                        gbCom.Text = "计算机基本信息";
                        tslAddOrSave.Text = "添加";
                        tslModify.Enabled = true;
                        tslDelete.Enabled = true;
                        tslClear.Enabled = true;
                    }
                    else
                    {
                        var index = this.dgvComputerInfo.Rows.Add();
                        dgvRow = dgvComputerInfo.Rows[index];
                    }
                   
                        dgvRow.Cells["selectedNode"].Value = cmbOrganization.SelectedNode;
                        dgvRow.Cells["comName"].Value = comName;//计算机名称
                        //dgvRow.Cells["Description"].Value = desc;//描述
                        dgvRow.Cells["ous"].Value = PROTOCOL + CONGIGURATION + "/" + cmbOrganization.SelectedNode.Tag;
                        dgvRow.Cells["Organization"].Value = cmbOrganization.SelectedNode.Text;
                       // dgvRow.Cells["dNSHostName"].Value = comName + "." + CONGIGURATION + ".com.cn";//DNS名称

                        //每行的序号赋值
                        for (var i = 0; i < dgvComputerInfo.Rows.Count; i++)
                        {
                            dgvComputerInfo.Rows[i].Cells[0].Value = i + 1;
                        }
                }
                catch (Exception ex)
                {
                    LogManager.WriteLog(ex.Message);
                }
            }
        }
        #endregion

        #region 创建计算机信息
        private void btnEstablish_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewRow row in dgvComputerInfo.Rows)
            {
                try
                {
                    var _comName = row.Cells["comName"].Value; //计算机名称
                   // var _Describe = row.Cells["Description"].Value; //描述
                    var _path = row.Cells["ous"].Value.ToString();

                    var entry = new DirectoryEntry(_path, UserName, Pwd, AuthenticationTypes.Secure);
                    var computer = entry.Children.Add("CN=" + _comName, "computer");
                    var _dNSHostName = row.Cells["dNSHostName"].Value;
                    computer.CommitChanges();

                    //创建域用户所有信息添加到对应的ad活动目录中
                    computer.Properties["sAMAccountName"].Value = _comName+"$";
                    computer.Properties["userAccountControl"].Value = 4128;
                    //computer.Properties["Description"].Value = _Describe;
                 
                    computer.CommitChanges();
                    computer.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return;
                }

            }
            int k = dgvComputerInfo.SelectedRows.Count;
            if (k > 0)
            {
                MessageBox.Show("已成功创建计算机信息！", "提示", MessageBoxButtons.OK, MessageBoxIcon.None);
                this.dgvComputerInfo.Rows.Clear(); //创建成功后，清空dgvComputerInfo里所有信息。
            }
        }
        #endregion

        #region 非空验证
        /// <summary>
        /// 非空验证
        /// </summary>
        /// <returns></returns>
        public bool verification(string comname)
        {
            #region 非空
            var reg = @"^[a-zA-Z0-9\.\-]+$";
            Match m = Regex.Match(txtComputerName.Text, reg);// 匹配正则表达式
            if (this.txtComputerName.Text == "")
            {

                //弹出提示信息"计算机名不能为空!"

                MessageBox.Show("计算机名称不能为空!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

                this.txtComputerName.Focus(); //使计算机名称文本框获得焦点

                return false; //跳出方法

            }
            else if(!m.Success)
            {
                MessageBox.Show("计算机名输入有误，请输入正确格式!如（dn-323）", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

                this.txtComputerName.Focus(); //使计算机名称文本框获得焦点

                return false; //跳出方法
            }

          
            //如果组织单位为空

            if (this.cmbOrganization.Text.Trim() == "")
            {

                //弹出提示信息"组织单位不能为空!"

                MessageBox.Show("组织单位不能为空!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

                this.cmbOrganization.Focus(); //使组织单位文本框获得焦点

                return false; //跳出方法

            }
            #endregion

            var flag = false;//是否已存在

            if (gbCom.Text != "修改")
            {
                //验证DataGridview中是否已添加
                foreach (DataGridViewRow row in dgvComputerInfo.Rows)
                {
                    if (row.Cells["comName"].Value.ToString() == comname)
                    {
                        flag = true;
                        break;
                    }
                }
            }
            //验证AD中计算名称是否已存在
            var entry = new DirectoryEntry(PROTOCOL + CONGIGURATION);
            var searcher = new DirectorySearcher(entry);
            searcher.Filter = "(&(objectCategory=computer)(cn=" + comname + "))";
            var result = searcher.FindOne();
            if ((result != null) || flag)
            {
                MessageBox.Show("已存在同名计算机名称!");
                txtComputerName.Text = "";
                txtDescribe.Text = "";
                return false;

            }
            return true;

        }
        #endregion

        #region 根据登录用户身份确定所属公司
        /// <summary>
        /// 根据用户身份确定所属公司
        /// </summary>
        private void InitCurrentCompany()
        {
            try
            {
                var computerName = Dns.GetHostName();
                var entry = new DirectoryEntry(PROTOCOL + CONGIGURATION, UserName, Pwd);
                var searcher = new DirectorySearcher(entry);
                searcher.Filter = "(&(objectCategory=computer)(cn=" + computerName + "))";
                var result = searcher.FindOne();
                WriteProperties(result);

                // lblCurrentCompany.Text = result.Properties["company"][0].ToString();
                var distinguishedname = result.Properties["distinguishedname"][0].ToString();
                var _a = distinguishedname.Split(',');
                var _b = new List<String>();
                for (var m = _a.Length - 5; m < _a.Length; m++)
                {
                    _b.Add(_a[m]);
                }
                _companyPath = PROTOCOL + CONGIGURATION + "/" + string.Join(",", _b);
            }
            catch (Exception)
            {

                throw;
            }


        }
        #endregion

        #region 把组织单元和用户节点捆绑到Treeview中
        /// <summary>
        /// 把组织单元和用户节点捆绑到Treeview中
        /// </summary>
        /// <returns></returns>
        public TreeNode GetAll()
        {

            try
            {
                var rootText = _companyPath.Split(',')[0].Substring(20);//根节点文本
                var rootNode = new TreeNode { Text = rootText, Tag = _companyPath.Substring(17) };//子节点文本
                var entry = new DirectoryEntry(_companyPath, UserName, Pwd);
                var mySearcher = new DirectorySearcher(entry) { Filter = "(objectClass=organizationalUnit)" };
                var results = mySearcher.FindAll();
                //將 LINQ 的查询字串转换成符合 RFC 2254 规格的 LDAP 查询过滤字串，再传送到 DirectorySearcher 物件中执行搜寻
                var list = (from SearchResult result in results select result.GetDirectoryEntry()).ToList();

                AddSubNode(rootNode, list);
                return rootNode;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return null;
        }


        /// <summary>
        /// 将子节点相对应的根节点使用递归一层一层添加到树中
        /// </summary>
        /// <param name="parentNode">父节点</param>
        /// <param name="results">集合</param>

        private void AddSubNode(TreeNode parentNode, List<DirectoryEntry> results)
        {
            for (var i = 0; i < results.Count; i++)
            {
                try
                {
                    var directoryEntry = results[i];
                    var distinguishedname = directoryEntry.Properties["distinguishedname"].Value.ToString();
                    var pOU = distinguishedname.Substring(distinguishedname.Split(',')[0].Length + 1);
                    if (pOU == parentNode.Tag.ToString())
                    {

                        var subNode = new TreeNode()
                        {
                            Text = distinguishedname.Split(',')[0].Substring(3),
                            Tag = distinguishedname
                        };
                        parentNode.Nodes.Add(subNode);
                        AddSubNode(subNode, results);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    throw ex;
                }

            }
        }
        #endregion

        /// <summary>
        /// 输出SearchResult对象的所有属性名及属性值到控制台
        /// </summary>
        /// <param name="de"></param>
        private void WriteProperties(SearchResult de)
        {
            if (de == null) return;
            var properties = de.Properties;
            var count = 1;
            foreach (DictionaryEntry p in properties)
            {
                Console.Write(count + ".  " + p.Key + ":");
                foreach (var v in (p.Value as ResultPropertyValueCollection))
                {
                    Console.WriteLine(v);

                }
                count++;
            }
        }
        #region 注销按钮事件
        private void button1_Click(object sender, EventArgs e)
        {
            isExit = false;
            this.Close();
            login.Show();
        }
        #endregion

    }
}
